.TH "basic-usage" 3 "Sun Sep 2 2018" "Version 2.0" "liblightmodbus" \" -*- nroff -*-
.ad l
.nh
.SH NAME
basic-usageBasic usage 
 \- If you want to get started with liblightmodbus, you should probably start here\&. This page shows basic usage of the library and assumes you have a working copy of it\&.
.PP
If you don't, see \fBBuilding liblightmodbus\fP or download a development package from the PPA\&.
.PP
The library consists of two independent parts\&. One contains all functions related with slave's tasks and the other functions related with master's tasks\&.
.PP
.SS "Slave side"
.PP
The most important structure type on the slave side is \fBModbusSlave\fP which represents slave device's status and configuration\&. A pointer to such structure is passed to all the slave-related functions\&.
.PP
.SS "Initialization"
.PP
In order to get started, you need to allocate some space for your slave's registers and coils\&. Two arrays will do just fine: 
.PP
.nf
uint16_t regs[16]; //16 holding registers
uint8_t coils[4];  //32 coils

.fi
.PP
.PP
Next, the slave structure has to be initialized: 
.PP
.nf
ModbusSlave slave;

//Tell the library where registers and coils are
slave\&.registers = regs;
slave\&.registerCount = 16;
slave\&.coils = coils;
slave\&.coilCount = 32;

//We don't have any input registers or discrete inputs
slave\&.inputRegisterCount = 0;
slave\&.discreteInputCount = 0;

//Setup slave's address
slave\&.address = 54;

assert( modbusSlaveInit( &slave ) == MODBUS_OK );

.fi
.PP
.PP
Note the \fBmodbusSlaveInit\fP call\&. This is the function that actually initializes the structure for use\&. It shall be called before any other library function is used on the structure
.PP
.SS "Processing requests"
.PP
Processing incoming requests is done using \fBmodbusParseRequest\fP function\&. However, before calling it, the request needs to be loaded to \fBModbusSlave::request\fP\&. Please see the example below\&. 
.PP
.nf
ModbusError err;
uint8_t length;
uint8_t frame[256];

//Get the incoming frame somehow
read_from_serial_somehow( &frame, &length );

//Pass the frame to the library
slave\&.request\&.frame = frame;
slave\&.request\&.length = length; 
err = modbusParseRequest( &slave );

//It is acceptable for slave to throw exceptions
assert( err == MODBUS_OK || err == MODBUS_ERROR_EXCEPTION );

.fi
.PP
.PP
This code causes the library to process the incoming request\&. Afterwards, the response from \fBModbusSlave::response\fP needs to be send back to master device\&. 
.PP
.nf
int i;
for ( i = 0; i < slave\&.response\&.length; i++ )
    serial_send_somehow( slave\&.response\&.frame[i] );

.fi
.PP
.PP
.SS "Cleaning up"
.PP
After you're done using the library, don't forget to clean up\&. You should call \fBmodbusSlaveEnd\fP on your slave structure\&.
.PP
.SS "Master side"
.PP
The most important structure type on the master side is \fBModbusMaster\fP which represents master device's status and configuration (like \fBModbusSlave\fP on the slave side)\&. A pointer to such structure is passed to all the master-related functions\&.
.PP
.SS "Initialization"
.PP
Unlike on save side, there's nothing more to be done apart from initializing the master structure with \fBmodbusMasterInit\fP\&. 
.PP
.nf
ModbusMaster master;
assert( modbusMasterInit( &master ) == MODBUS_OK );

.fi
.PP
.PP
.SS "Forming requests"
.PP
Request frames can be generated using \fCmodbusBuildRequest**\fP functions\&. After each successful call, the new request frame will be written to \fBModbusMaster::request\fP\&. 
.PP
.nf
//Write 678 to 7th register of slave 54
assert( modbusBuildRequest( &master, 54, 7, 678 ) == MODBUS_OK );

//Send
for ( i = 0; i < master\&.request\&.length; i++ )
    serial_send_somehow( master\&.request\&.frame[i] );

.fi
.PP
.PP
.SS "Parsing responses"
.PP
The \fBmodbusParseResponse\fP function does the response parsing job on the master side\&. It needs to have the response frame provided in \fBModbusMaster::response\fP\&. After successful parsing, the incoming data will be available in \fBModbusMaster::data\fP structure\&. If the slave had returned an exception, the exception details will be available in the \fBModbusMaster::exception\fP structure\&. 
.PP
.nf
ModbusError err;
uint8_t length;
uint8_t frame[256];

//Get the incoming frame somehow
read_from_serial_somehow( &frame, &length );

//Pass the frame to the library
master\&.response\&.frame = frame;
master\&.response\&.length = length;
err = modbusParseResponse( &master );

if ( err == MODBUS_OK )
{
    //Use the data
    //see ModbusMaster::data
}
else if ( err == MODBUS_ERROR_EXCEPTION )
{
    //Use the exception information
    printf( "slave threw an exception - %d\n", master\&.exception\&.code );
}
else
{
    //Handle the other errors
    //see ModbusError
}

.fi
.PP
.PP
.SS "Cleaning up"
.PP
After you're done using the library, don't forget to clean up\&. You should call \fBmodbusMasterEnd\fP on your master structure\&.
.PP
.SS "Examples"
.PP
Please see the contents of the \fCexamples\fP directory\&. 
